package com.syl.whitelist;

import cn.hutool.core.bean.BeanUtil;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import com.alibaba.fastjson.JSON;
import com.syl.whitelist.annotation.WhiteList;
import com.syl.whitelist.utils.AspectUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;
import javax.annotation.Resource;
import java.lang.reflect.Parameter;
import java.util.Objects;

/**
 * @ClassName Joinpoint
 * @Description 切面类
 * @Author YunLong
 * @Date 2022/8/19 14:57
 */
@Aspect
public class JoinPoint {
    private Logger logger = LoggerFactory.getLogger(JoinPoint.class);

    @Resource
    private String whiteListConfig;

    @Pointcut("@annotation(com.syl.whitelist.annotation.WhiteList)")
    public void point() {
    }

    @Around("point()")
    public Object filter(ProceedingJoinPoint joinPoint) throws Throwable {

        // 获取注解内容值
        WhiteList whiteList = AspectUtils.getAnnotation(joinPoint, WhiteList.class);
        Class<?> returnType = AspectUtils.getReturnType(joinPoint);

        String filed = whiteList.key();

        // 获取字段值
        Object filedValue = getFiledValue(joinPoint, filed);

        if (Objects.isNull(filedValue)) {
           return returnObject(whiteList, returnType);
        }
        if ("".equals(filedValue.toString())) {
            return returnObject(whiteList, returnType);
        }

        String[] split = whiteListConfig.split(",");
        for (String str : split) {
            if (filedValue.toString().equals(str)) {
                return joinPoint.proceed();
            }
        }


        Object returnObject = returnObject(whiteList, returnType);

        return returnObject;
    }

    private Object returnObject(WhiteList whiteList, Class<?> returnType) throws IllegalAccessException, InstantiationException {
        String json = whiteList.returnJson();
        if ("".equals(json)) {
            return returnType.newInstance();
        }

        return JSON.parseObject(json, returnType);
    }

    private Object getFiledValue(ProceedingJoinPoint joinPoint, String filed) {
        Parameter[] params = AspectUtils.getParams(joinPoint);
        Object filedValue = null;
        Object[] args = joinPoint.getArgs();
        for (int i = 0; i < params.length; i++) {


            RequestParam requestParam = params[i].getAnnotation(RequestParam.class);

            if (Objects.nonNull(requestParam)) {

                String key = params[i].getName();
                if (!StringUtils.isEmpty(requestParam.value())) {
                    key = requestParam.value();
                }
                if (filed.equals(key)) {
                    filedValue = args[i];
                }
            }

            RequestBody requestBody = params[i].getAnnotation(RequestBody.class);
            if (Objects.nonNull(requestBody)) {
                filedValue = BeanUtil.getFieldValue(args[i], filed);
            }
        }

        return filedValue;
    }


}
